/**
 *
 * @description:
 * @author: junyong.hong
 * @createTime: 2018/10/10
 * @version: 1.0.0.0
 * @history:
 *    1、
 *    2、
 *
 */
// 解析xml模块
const xml2js = require('xml2js')
const template = require('./tpl')
const sha1 = require('sha1')

exports.parseXML = xml => {
    return new Promise((resolve, reject) => {
        // 固定用法
        xml2js.parseString(xml, {trim: true}, (err, content) => {
            if (err) {
                reject(err)
            } else {
                resolve(content)
            }
        })
    })
}

// 把xml解析成json对象
const formatMessage = result => {
    let message = {}

    // 本身是一个对象
    if (typeof result === 'object') {
        const keys = Object.keys(result)

        for (let i=0;i<keys.length;i++) {
            // 拿到每条数据
            let item = result[keys[i]]
            let key = keys[i]

            // 不是一个数组
            if (!(item instanceof Array) || item.length === 0) {
                continue
            }

            if (item.length === 1) {
                let val = item[0]

                if (typeof val === 'object') {
                    message[key] = formatMessage(val)
                } else {
                    message[key] = (val || '').trim()
                }
            } else {
                message[key] = []

                for (let j=0;j<item.length;j++) {
                    message[key].push(formatMessage(item[j]))
                }
            }
        }
    }
    return message
}

exports.tpl = (content, message) => {
    let type = 'text'

    // 是数组
    if (Array.isArray(content)) {
        type = 'news'
    }

    if (!content) {
        content = 'Empty News'
    }

    // 可能是非图文非纯文本，可能是一个语音或视频
    if (content && content.type) {
        type = content.type
    }

    let info = Object.assign({}, {
        content: content,
        msgType: type,
        createTime: new Date().getTime(),
        // 谁发给我的（进行反转）
        toUserName: message.FromUserName,
        fromUserName: message.ToUserName
    })

    // 调用微信xml回复模版（调用wechat-lib/tpl.js）
    return template(info)

}

// 生成随机串
const createNonce = () => {
    return Math.random().toString(36).substr(2, 16)
}

// 生成时间戳
const createTimestame = () => {
    return parseInt(new Date().getTime() / 1000, 10) + ''
}

/**
 * 字典排序
 * @param paramsObj
 * @returns {string}
 */
const signIt = (paramsObj) => {
    let keys = Object.keys(paramsObj)
    let newArgs = {}
    let str = ''

    keys = keys.sort()
    keys.forEach(key => {
        newArgs[key.toLowerCase()] = paramsObj[key]
    })

    for (let k in newArgs) {
        str += '&' + k + '=' + newArgs[k]
    }

    return str.substr(1)
}

/**
 * 加密
 * @param nonce
 * @param ticket
 * @param timestamp
 * @param url
 * @returns {*}
 */
const shaIt = (nonce, ticket, timestamp, url) => {
    const ret = {
        jsapi_ticket: ticket,
        nonceStr: nonce,
        timestamp: timestamp,
        url
    }

    const str = signIt(ret)
    const sha = sha1(str)

    return sha
}

/**
 * 加密签名的入口方法
 * @param ticket
 * @param url
 * @returns {{noncestr, timestamp, signature}}
 */
const sign = (ticket, url) => {
    // 生成随机串
    const noncestr = createNonce()
    // 生成时间戳
    const timestamp = createTimestame()
    // 加密
    const signature = shaIt(noncestr, ticket, timestamp, url)

    console.log('noncestr', noncestr)
    console.log('timestamp', timestamp)
    console.log('signature', signature)
    return {
        noncestr,
        timestamp,
        signature
    }
}

exports.sign = sign

exports.formatMessage = formatMessage